import Vue from 'vue'
import VueRouter from 'vue-router'
import Vuex from 'vuex'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import directives from '@daelui/vdog/dist/directives.js'
import dog from '@daelui/dogjs/dist/index.js'
import '@daelui/dogui/dist/css/boost.min.css'
import '@daelui/dogui/dist/css/theme/black.min.css'
import { parser } from '@daelui/dogjs/dist/components.js'
import App from './runtime.vue'
import ds from '@/service/components/ds'
import componentCollection from '@/views/dview/page/components/components.js'

Vue.config.productionTip = false

Vue.use(VueRouter)
Vue.use(Vuex)
Vue.use(ElementUI)

// 指令
directives(Vue)

const win = typeof self !== 'undefined' ? window : global
var $dog = win.$dog
if ($dog) {
  for (let key in $dog) {
    dog[key] = $dog[key]
  }
}
win.$dog = $dog = dog
win.$dog.Vue = win.$dog.Vue || Vue
win.Vue = Vue

let microPath = ''
Vue.prototype.getMicroPath = function (path) {
  return path.replace('#', '#' + microPath).replace(/\/+/, '/')
}

// 状态
const store = new Vuex.Store({ state: {} })
// 配置
let setting = {
  page: '/'
}
// 启动
const bootstrap = function ({ appName, routes, rootPath, config, registryMap } = {}) {
  // 导航解析
  let navList = solveNav(routes, rootPath)
  // 路由解析
  routes = solveRoute(navList)
  // 路由生成
  const router = new VueRouter({
    routes: routes
  })
  // 配置
  config = config || {}
  Object.assign(setting, config)
  // 组件注册表
  registryMap = registryMap || []

  // 视图挂载
  new Vue({
    router,
    store,
    render: h => h(App, {
      props: {
        appName: appName,
        navList: navList
      }
    })
  }).$mount('#micro-app')
}

export {
  Vue, Vuex, VueRouter, App, bootstrap, store
}

// 导航解析
function solveNav (list, parentPath, topPath) {
  list = Array.isArray(list) ? list : []
  parentPath = parentPath || ''
  list.forEach(item => {
    item.text = item.name
    let path = item.path || item.id
    let navPath = ('/' + (parentPath + '/' + path)).replace(/\/+/g, '/').replace(/\/+$/g, '')
    item.url = '#' + navPath
    // 非一层路径则使用子路径
    item.path = topPath ? path : navPath
    // 一层匹配路径
    let matchPath = topPath ? topPath : navPath
    item.match = matchPath
    // 子级菜单
    if (item.children) {
      solveNav(item.children, navPath, matchPath)
    }
  })

  return list
}

// 路由解析
function solveRoute (list, routes, parentRoute) {
  list = Array.isArray(list) ? list : []
  routes = Array.isArray(routes) ? routes : []
  parentRoute = parentRoute || {}
  list.forEach(item => {
    let node = {
      path: parentRoute.path ? parentRoute.path + '/' + item.path : item.path,
      component: resolve => getRender(item, resolve)
    }
    routes.push(node)
    // 子级菜单
    if (item.children) {
      solveRoute(item.children, routes, node)
    }
  })

  return routes
}

// 获取渲染器
async function getRender (data, resolve) {
  let res = await $pig.import('@daelui/drender/dist/drender.umd.min.js')
  let stock = res.stock
  if (!stock.state.isInitComponents) {
    stock.state.isInitComponents = true
    Vue.component('drender', res)
    stock.setter.setComponentCollection(componentCollection)

    // 查询组件
    try {
      let defer = Promise.resolve([])
      if (setting.components) {
        let url = setting.components
        for (let key in data) {
          url = url.replace('{' + key + '}', data[key])
        }
        defer = ds.get(url).then(res => {
          let list = []
          if (Array.isArray(res)) {
            list = res
          } else {
            let data = res.data || res.list || res.result
            data = Array.isArray(data) ? data : []
            list = data
          }
          return list
        })
      }
      await defer.then(cps => {
        stock.setter.setComponentCollection(cps)
      })
    } catch (e) {
      console.log(e)
    }
  }

  // 加载页面元数据
  let page = await loadPage(data)
  const comp = Vue.extend({
    template: '<component :page="page" is="drender" />',
    data () {
      return {
        page: page
      }
    }
  })
  resolve(comp)
}

// 加载页面
function loadPage (page) {
  let url = setting.page
  for (let key in page) {
    url = url.replace('{' + key + '}', page[key])
  }
  return ds.get(url).then(result => {
    let data = result.vpid ? result : result.data || {}
    // 组件元数据
    let meta = parser.parse(data.meta) || {
      component: 'div',
      properts: {},
      events: {},
      resource: {},
      theme: {},
      childComponents: []
    }
    meta.childComponents = meta.childComponents || []
    data.meta = meta
    return data
  })
}